package threads.cas;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class CasTest {
    ConcurrentHashMap<Long,Long> map = new ConcurrentHashMap();
    ConcurrentHashMap<String,Long> map1 = new ConcurrentHashMap(134);
    public static VarHandle idVarHandle ;
    static {
        try {
            idVarHandle = MethodHandles.lookup().findVarHandle(CasTest.class, "id", Integer.class);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    //让锁得级别缩小
    private Integer id;

    public static void main1(String[] args) throws NoSuchMethodException, IllegalAccessException {
        int count = 100;
        System.out.println(1+(int)(count/0.75));
//        CasTest test = new CasTest();
//        for (long i = 0; i < 128; i++) {
//            test.map.put(i, i);
//        }
//
//        Long v = test.map.putIfAbsent(10000002L, 1L);
//        System.out.println(v);

    }
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException {
        CasTest test = new CasTest();
        for (long i = 0; i < 99; i++) {
            test.map1.put("abcdefghefefefefefssssssssssssssddddddddddddddddddeeeeeeeeeee"+i, i);
        }

        Long v = test.map1.putIfAbsent("abcdefghefefefefefssssssssssssssddddddddddddddddddeeeeee"+10000002+"", 1L);
        System.out.println(v);

    }

    @org.junit.Test
    public void perfect() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        int count = 1000000;

        int initCapacity = 1 + (int) (count / 0.75);
        ConcurrentHashMap<Integer, Object> map = new ConcurrentHashMap<>(initCapacity);
        Method capacityMethod = map.getClass().getDeclaredMethod("transfer",ConcurrentHashMap.class);
        capacityMethod.setAccessible(true);
        int capacity = (int) capacityMethod.invoke(map);
        System.out.println("jdk hashMap default capacity:" + capacity);
        int resizeCount = 0;
        for (int i = 0; i < count; i++) {
            map.put(i, UUID.randomUUID());
            int curCapacity = (int) capacityMethod.invoke(map);
            if (curCapacity > capacity) {
                System.out.println("当前容量：" + curCapacity);
                resizeCount++;
                capacity = curCapacity;
            }
        }
        System.out.println("hashMap扩容次数：" + resizeCount);
    }

}
